package cloudContact.DAO;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Hashtable;

import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;
import org.scribe.model.Token;
import org.scribe.model.Verb;
import org.scribe.oauth.OAuthService;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import cloudContact.FacebookManager;

public class FacebookContactDAO {
	private JsonObject contactObject;
	
	private String session = null;
	private static Hashtable<String, FacebookContactDAO> instances = new Hashtable<String, FacebookContactDAO>();	
	public static FacebookContactDAO getInstance(String sessionId, String userId, String accessToken) throws IOException{
		FacebookContactDAO instance;
		if (!instances.containsKey(sessionId)){
			instance = new FacebookContactDAO(userId, accessToken);
			instance.session = sessionId;
			instances.put(sessionId, instance);
		}else{
			instance = instances.get(sessionId);
		}
		return instance;
	}

	private FacebookContactDAO(String userId, String accessToken)
			throws IOException {
		OAuthService service = FacebookManager.getOAuthService();
		OAuthRequest request = new OAuthRequest(Verb.GET,
				"https://graph.facebook.com/" + userId + "/friends");
		service.signRequest(new Token(accessToken, ""), request);
		Response response = request.send();

		System.out.println(response.getCode());
		System.out.println(response.getBody());
		JsonParser parser = new JsonParser();
		contactObject = parser.parse(response.getBody()).getAsJsonObject();

		System.out.println("FacebookContactDAO is constructed.");
		// URL theURL = new URL("https://graph.facebook.com/" + userId +
		// "/friends?accessToken=" + accessToken);
		// BufferedReader in = new BufferedReader(new
		// InputStreamReader(theURL.openStream()));
		//
		// StringBuilder reply = new StringBuilder();
		// String line = "";
		// while((line = in.readLine()) != null){
		// reply.append(line);
		// }
		//
		// JsonParser parser = new JsonParser();
		// contactObject = parser.parse(reply.toString()).getAsJsonObject();
	}

	private FacebookContact[] contacts;

	public FacebookContact lookup(String id) throws IOException{
		getAllContacts();
		for (FacebookContact contact : contacts){
			if (contact.getId().equals(id))
				return contact;
		}
		return null;
	}
	
	public FacebookContact[] getAllContacts() throws IOException {
		System.out.println("Start getAllContacts...");
		if (contacts != null)
			return contacts;

		JsonArray jArray = contactObject.getAsJsonArray("data");
		contacts = new FacebookContact[jArray.size()];
		int size = contacts.length;
		for (int i = 0; i < size ; i++) {
			FacebookContact contact = new FacebookContact(jArray.get(i)
					.getAsJsonObject().get("id").getAsString());
			contacts[i] = contact;
		}
		System.out.println("Finish getAllContacts.");
		return contacts;
	}

	public ArrayList<FacebookContact> getPossibleMatchedContacts(GoogleContact gcontact)
			throws IOException {
		System.out.println("Start getPossibleMatchedContacts...");
		try {
			if (contacts == null)
				getAllContacts();
			ArrayList<FacebookContact> strictMatched = new ArrayList<FacebookContact>();
			ArrayList<FacebookContact> matched = new ArrayList<FacebookContact>();
			String fullName = gcontact.getFullName();
			String firstName = gcontact.getFirstName();
			String lastName = gcontact.getLastName();
			
			// most strict
			int size = contacts.length;
			for (int i = 0 ; i < size; i++){
				FacebookContact fcontact = contacts[i]; 
				boolean matchFullName = fcontact.getFullName().equals(fullName);
				boolean matchFirstLastName = fcontact.getFirstName().equals(firstName) 
					&& fcontact.getLastName().equals(lastName);

				if (matchFullName && matchFirstLastName)
				{
					strictMatched.add(fcontact);
				}
				if (matchFullName || matchFirstLastName)
				{
					matched.add(fcontact);
				}
			}
			
			if (strictMatched.size() > 0)
				return  strictMatched;
			
			if (matched.size() > 0)
				return  matched;
			
			if (matched.size() > 0) {
				System.out.println("Found match:" + matched.size());
				
				return matched;
			} else {
				System.out.println("Found no match");
			}
				

			return null;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			System.out.println("Finish getPossibleMatchedContacts.");
		}
		return null;
	}
}
